<template>
  <CollapseContainer title="基础配置">
    <BasicForm @register="register" />
  </CollapseContainer>

  <CollapseContainer title="参数配置">
    <BasicForm @register="basicRegister" />
  </CollapseContainer>

  <CollapseContainer
    title="主表配置"
    v-show="tplType !== TemplateTypeEnum.MERGE"
  >
    <BasicForm @register="baseRegister" />
  </CollapseContainer>

  <CollapseContainer
    title="树表配置"
    v-show="
      tplType === TemplateTypeEnum.TREE || tplType === TemplateTypeEnum.SUB_TREE
    "
  >
    <BasicForm @register="treeRegister" />
  </CollapseContainer>

  <CollapseContainer
    title="主子表配置"
    v-show="
      tplType === TemplateTypeEnum.SUB_BASE ||
      tplType === TemplateTypeEnum.SUB_TREE
    "
  >
    <BasicForm @register="subRegister" />
  </CollapseContainer>
</template>

<script lang="ts">
import { CollapseContainer } from '@/components/Container'
import { BasicForm, useForm } from '@/components/Form'
import { TemplateTypeEnum } from '@enums/gen'
import { GenTableIM, OptionIM } from '@type/gen'
import { defineComponent, reactive, ref } from 'vue'
import {
  dict,
  generateBaseSchema,
  generateBasicSchema,
  generateFormSchema,
  generateSubSchema,
  generateTreeSchema,
  genList,
  getOptions,
} from './gen.detail.data'
import { sourceAssign } from '@admin/utils'
import { listGenApi, listGenColumnApi } from '@service/gen/generate/gen'
import { getMenuRouteListApi } from '@service/system/authority/menu'
import { MenuTypeEnum } from '@enums/system'

export default defineComponent({
  name: 'GenerateFrom',
  components: { BasicForm, CollapseContainer },
  emits: ['submit'],
  setup(_, { emit }) {
    const state = reactive<{
      info: Nullable<GenTableIM>
    }>({
      info: null,
    })

    const tplType = ref<TemplateTypeEnum>(TemplateTypeEnum.BASE)

    const [register, { setFieldsValue, validate, updateSchema }] = useForm({
      labelWidth: 160,
      schemas: generateFormSchema,
      showActionButtonGroup: false,
    })

    const [
      basicRegister,
      { setFieldsValue: basicSetFieldsValue, validate: basicValidate },
    ] = useForm({
      labelWidth: 160,
      schemas: generateBasicSchema,
      showActionButtonGroup: false,
    })

    const [
      baseRegister,
      {
        setFieldsValue: baseSetFieldsValue,
        validate: baseValidate,
        updateSchema: baseUpdateSchema,
      },
    ] = useForm({
      labelWidth: 160,
      schemas: generateBaseSchema,
      showActionButtonGroup: false,
    })

    const [
      treeRegister,
      {
        setFieldsValue: treeSetFieldsValue,
        validate: treeValidate,
        updateSchema: treeUpdateSchema,
      },
    ] = useForm({
      labelWidth: 160,
      schemas: generateTreeSchema,
      showActionButtonGroup: false,
    })

    const [
      subRegister,
      {
        setFieldsValue: subSetFieldsValue,
        validate: subValidate,
        updateSchema: subUpdateSchema,
      },
    ] = useForm({
      labelWidth: 160,
      schemas: generateSubSchema,
      showActionButtonGroup: false,
    })

    /** 数据初始化 */
    function initialize(info: GenTableIM) {
      state.info = info
      tplType.value = state.info.tplCategory as TemplateTypeEnum
      initBasic()
      const dataList =
        state.info.subList === undefined ? [] : getOptions(state.info.subList)
      const option = JSON.parse(state.info?.options) as OptionIM
      initBase(dataList, option)
      initTree(dataList)
      initSub(dataList, option)
      basicSetFieldsValue({ ...option })
      subSetFieldsValue({ ...option })
      treeSetFieldsValue({ ...option })
      baseSetFieldsValue({ ...option })
    }

    /** 基础配置初始化 */
    function initBasic() {
      setFieldsValue({ ...state.info })
      updateSchema({
        field: 'tplCategory',
        componentProps: () => {
          return {
            options: dict.templateType,
            onChange: (e: any) => {
              tplType.value = e
            },
          }
        },
      })
    }

    /** 单表配置初始化 */
    async function initBase(subList: any[], options: OptionIM) {
      const parentMenuIdOptions =
        options?.parentModuleId === undefined
          ? []
          : await getMenuRouteListApi(options?.parentModuleId, MenuTypeEnum.DIR)
      baseUpdateSchema([
        {
          field: 'parentMenuId',
          componentProps: { treeData: parentMenuIdOptions },
        },
        { field: 'id', componentProps: { options: subList } },
        { field: 'name', componentProps: { options: subList } },
        { field: 'status', componentProps: { options: subList } },
        { field: 'sort', componentProps: { options: subList } },
      ])
    }

    /** 树表配置初始化 */
    function initTree(subList: any[]) {
      treeUpdateSchema([
        { field: 'treeCode', componentProps: { options: subList } },
        { field: 'parentId', componentProps: { options: subList } },
        { field: 'treeName', componentProps: { options: subList } },
        { field: 'ancestors', componentProps: { options: subList } },
      ])
    }

    /** 主子表配置初始化 */
    async function initSub(subList: any[], options: OptionIM) {
      if (options?.subTableId !== undefined) {
        const subForeignOptions = await listGenColumnApi(
          options?.subTableId,
        ).then((res) => {
          return getOptions(res.items)
        })
        subUpdateSchema({
          field: 'subForeignId',
          componentProps: { options: subForeignOptions },
        })
      }
      const data = await listGenApi().then((res) => {
        return getOptions(res.items)
      })
      subUpdateSchema([
        { field: 'foreignId', componentProps: { options: subList } },
        {
          field: 'subTableId',
          componentProps: ({ formModel, formActionType }) => {
            return {
              options: data,
              showSearch: true,
              optionFilterProp: 'label',
              onChange: async (e: any) => {
                formModel.subForeignId = undefined
                const { updateSchema } = formActionType
                const data =
                  e === undefined
                    ? []
                    : await listGenColumnApi(e).then((res) => {
                        return getOptions(res.items)
                      })
                updateSchema({
                  field: 'subForeignId',
                  componentProps: { options: data },
                })
              },
            }
          },
        },
      ])
    }

    /** 保存校验 */
    async function submit() {
      try {
        sourceAssign(state.info, await validate())
        let options = {}
        sourceAssign(options, await basicValidate())
        switch (tplType.value) {
          case TemplateTypeEnum.TREE:
            sourceAssign(options, await treeValidate())
            sourceAssign(options, await baseValidate())
            break
          case TemplateTypeEnum.SUB_TREE:
            sourceAssign(options, await treeValidate())
          case TemplateTypeEnum.SUB_BASE:
            sourceAssign(options, await subValidate())
          case TemplateTypeEnum.BASE:
            sourceAssign(options, await baseValidate())
        }
        sourceAssign(state.info, { options: JSON.stringify(options) })
      } catch {
        emit('submit', genList[1].key)
      }
    }

    return {
      register,
      basicRegister,
      baseRegister,
      treeRegister,
      subRegister,
      initialize,
      submit,
      tplType,
      TemplateTypeEnum,
    }
  },
})
</script>
